﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Net;


namespace Apex.ASPNETCore.GlobalException
{
    /// <summary>
    /// 
    /// </summary>
    public class GlobalResponseResultFilter : ActionFilterAttribute, IAsyncExceptionFilter, IAsyncActionFilter
    {
        /// <summary>
        /// 处理接口中IActionResult类型错误
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            // 执行下一个过滤器或操作
            var result = await next();

            // 异常错误处理：有报错信息就在别的地方处理
            if (result.Exception == null)
            {
                // 处理Controller中，IActionResult类型返回值，BadRequest或者其它的“错误返回”
                if (result.Result is ObjectResult actionResult)
                {
                    int? statusCode = actionResult.StatusCode; // 通过 StatusCode 属性获取状态码
                    if (statusCode != 200 && statusCode != null) // 接口返回值不是200类型
                    {
                        var newObjectResult = new ObjectResult(GlobalResponseResultHelper.CreateErrorResponse(statusCode ?? 400, actionResult.Value.ToString()))
                        {
                            StatusCode = statusCode ?? 400
                        };
                        result.Result = newObjectResult; // 替换原始的结果
                    }
                }
            }
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            var actionWrapper = controllerActionDescriptor?.MethodInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
            var controllerWrapper = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
            //如果包含NoWrapperAttribute则说明不需要对返回结果进行包装，直接返回原始值
            if (actionWrapper != null || controllerWrapper != null)
            {
                return;
            }

            var rspResult = new GlobalResponseResult<object>();
            if (context.Result is ObjectResult)
            {
                var objectResult = context.Result as ObjectResult;
                if (objectResult.DeclaredType != null)
                {
                    // 如果返回结果已经是ResponseResult<T>类型的则不需要进行再次包装了
                    if (objectResult.DeclaredType.IsGenericType && objectResult.DeclaredType?.GetGenericTypeDefinition() == typeof(GlobalResponseResult<>))
                    {
                        return;
                    }
                }
                else
                {
                    // 如果结果是 OkObjectResult，则检查其 Value 是否为 ResponseRes<T>
                    if (objectResult.Value != null && objectResult.Value.GetType().IsGenericType &&
                        objectResult.Value.GetType().GetGenericTypeDefinition() == typeof(GlobalResponseResult<>))
                    {
                        return;
                    }
                }
                rspResult.StatusCode = 200;
                rspResult.Message = "Success";
                rspResult.Data = objectResult.Value;
                context.Result = new ObjectResult(rspResult);

                return;
            }

            if (context.Result is OkResult)
            {
                var objectResult = context.Result as OkResult;
                if (objectResult.StatusCode == 200)
                {
                    rspResult.StatusCode = 200;
                    rspResult.Message = "Success";
                    rspResult.Data = null;
                    context.Result = new ObjectResult(rspResult);

                }
            }
        }

        /// <summary>
        /// 处理报错信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnExceptionAsync(ExceptionContext context)
        {
            GlobalResponseResult<string> serialzeStr = null;
            // 如果是参数报错，参数报错内容需要对前端做显示
            if (context.Exception is ArgumentException argEx)
            {
                serialzeStr = GlobalResponseResultHelper.CreateErrorResponse(400, argEx.Message);
            }
            else
            {
                serialzeStr = GlobalResponseResultHelper.CreateErrorResponse(400);
            }
            context.Result = new ObjectResult(serialzeStr)
            {
                StatusCode = 400
            };
            context.ExceptionHandled = true; // 表示异常已经处理
            return Task.CompletedTask;
        }
    }
}
